import fs from 'fs';
import path from 'path';
import ffmpeg from 'fluent-ffmpeg';

export function getFileInDirectorySync(directory: string, targetFileName: string) {
  try {
    const files = fs.readdirSync(directory);

    for (const file of files) {
      if (file === targetFileName) {
        return path.join(directory, file); // 返回完整路径
      }
    }

    return null; // 文件未找到
  } catch (error) {
    console.error('读取目录出错:', error);
    return null;
  }
}

export async function getFileInDirectory(
  directory: string,
  targetFileName: string
): Promise<string | null> {
  try {
    const files = await fs.promises.readdir(directory);

    for (const file of files) {
      if (file === targetFileName) {
        return path.join(directory, file);
      }
    }

    return null;
  } catch (error) {
    console.error('readdirectory.err:', error);
    return null;
  }
}

export async function readFileContentAsync(filePath: string): Promise<string> {
  try {
    return await fs.promises.readFile(filePath, 'utf-8');
  } catch (error) {
    console.error('readfile.err:', error);
    throw error;
  }
}

export async function readFileStream(filePath: string): Promise<string> {
  try {
    const stream = fs.createReadStream(filePath);
    return new Promise<string>((resolve, reject) => {
      const chunks: (Buffer | string)[] = [];
      stream.on('data', (chunk: Buffer | string) => {
        chunks.push(chunk);
      });
      stream.on('end', () => {
        // 统一转换为 Buffer
        const buffer = chunks.every((c) => typeof c === 'string')
          ? Buffer.from(chunks.join(''), 'utf8') // 全部是字符串
          : Buffer.concat(chunks as Buffer[]); // 全部是 Buffer
        resolve(buffer.toString('base64'));
      });
      stream.on('error', reject);
    });
  } catch (error) {
    console.error('readfile.err:', error);
    throw error;
  }
}

export function readFileBuffer(filePath: string): string {
  try {
    return fs.readFileSync(filePath).toString('base64');
  } catch (error) {
    console.error('readfile.err:', error);
    throw error;
  }
}

export async function readFileBlob(filePath: string): Promise<ArrayBuffer> {
  try {
    const blob = await fs.openAsBlob(filePath);
    return await blob.arrayBuffer();
  } catch (error) {
    console.error('readfile.err:', error);
    throw error;
  }
}

export async function getVideoMetadata(filePath: string): Promise<VideoInfo> {
  // 获取文件大小
  const stats = await fs.promises.stat(filePath);
  const fileSize = stats.size;

  return new Promise((resolve, reject) => {
    ffmpeg.ffprobe(filePath, (err, metadata) => {
      if (err) {
        return reject(new Error(`FFprobe 错误: ${err.message}`));
      }

      try {
        const videoStream = metadata.streams.find((s) => s.codec_type === 'video');
        const audioStream = metadata.streams.find((s) => s.codec_type === 'audio');
        const format = metadata.format;

        if (!videoStream || !format) {
          return reject(new Error('无法解析视频信息'));
        }

        const result: VideoInfo = {
          width: videoStream.width || 0,
          height: videoStream.height || 0,
          duration: format?.duration ?? 0,
          format: format.format_name || path.extname(filePath).slice(1),
          codec: videoStream.codec_name || '',
          fileSize,
          bitRate: format.bit_rate
        };

        // 计算帧率 (如果有)
        if (videoStream.avg_frame_rate) {
          const [numerator, denominator] = videoStream.avg_frame_rate.split('/');
          if (denominator && numerator) {
            result.frameRate = parseInt(numerator) / parseInt(denominator);
          }
        }

        // 音频信息 (如果有)
        if (audioStream) {
          result.audioCodec = audioStream.codec_name;
          result.audioChannels = audioStream.channels;
        }

        resolve(result);
      } catch (parseError) {
        reject(new Error(`解析元数据失败: ${parseError}`));
      }
    });
  });
}

/**
 * 写入文件（如果存在则替换）
 * @param dir 目录路径
 * @param filename 文件名
 * @param content 文件内容
 */
export async function writeFileReplace(dir: string, filename: string, content: string) {
  const filePath = path.join(dir, filename);
  // 确保目录存在（如果不存在则创建）
  await fs.promises.mkdir(dir, { recursive: true });

  await fs.promises.writeFile(filePath, content);
  console.log(`文件已写入: ${filePath}`);
}
